<?php

namespace App\Formats;

use App\Common\Libs\Ali\Oss;
use App\Common\Libs\ArrayHelper;
use App\Common\Libs\IdBuilder;
use App\Common\Libs\Json;
use App\Consts\GlobalArticleConst;
use App\Consts\GlobalConst;
use App\Consts\GlobalDynamicConst;
use App\Consts\GlobalUploadConst;
use App\Models\Cache\CacheKey;
use App\Models\Field\ArticleField;
use App\Models\Field\UserField;
use App\Models\Select\ArticleSelect;
use App\Models\Select\UserSelect;
use App\Models\SysArticle;

class ArticleFormat extends BaseFormat
{
    // 用户文章列表
    public const USER_ARTICLE_LIST = 'userArticleList';

    // 广场关注列表
    public const SQUARE_ATTENTION_LIST = 'squareAttentionList';

    // 广场推荐列表
    public const SQUARE_RECOMMEND_LIST = 'squareRecommendList';

    // 相关文章列表
    public const SIMILAR_ARTICLE_LIST = 'similarArticleList';

    public const HOME_COLLECT_LIST = 'homeCollectList';

    public function formatArticleList($articleIds, $currentUserId, $formatScene)
    {
        switch ($formatScene) {
            case self::USER_ARTICLE_LIST:
                return self::formatByUserArticleList($articleIds, $currentUserId);
            case self::HOME_COLLECT_LIST:
            case self::SQUARE_ATTENTION_LIST:
                return self::formatBySquareAttentionList($articleIds, $currentUserId);
            case self::SQUARE_RECOMMEND_LIST:
                return self::formatBySquareRecommendList($articleIds, $currentUserId);
            case self::SIMILAR_ARTICLE_LIST:
                return self::formatBySimilarArticleList($articleIds);
        }

        return [];
    }

    public static function formatByUserArticleList($articleIds, $currentUserId)
    {
        $articleArr = self::getArticleArr($articleIds);
        $authorArr = UserFormat::getUserArr(ArrayHelper::getColumn($articleArr, 'author_id'), UserSelect::ARTICLE);

        $list = [];
        /**
         * @var SysArticle $article
         */
        foreach ($articleArr as $article) {
            $list[] = ArrayHelper::merge($article->commonFormat(), [
                'author' => isset($authorArr[$article->author_id]) ? $authorArr[$article->author_id]->commonFormat() : (object)[],
                'target_type' => GlobalConst::TARGET_TYPE_ARTICLE,
                'count' => service()->CounterService->getArticleCount($article->article_id, $currentUserId, [
                    'collect',
                    'note',
                    'recommend'
                ])
            ]);
        }

        return $list;
    }

    public static function formatBySquareAttentionList($articleIds, $currentUserId)
    {
        $articleArr = self::getArticleArr($articleIds);

        $list = [];
        /**
         * @var SysArticle $article
         */
        foreach ($articleArr as $article) {
            $list[] = ArrayHelper::merge($article->commonFormat(), [
                'target_type' => GlobalConst::TARGET_TYPE_ARTICLE,
                'count' => service()->CounterService->getArticleCount($article->article_id, $currentUserId, [
                    'collect',
                    'note',
                    'recommend'
                ])
            ]);
        }

        return $list;
    }

    public static function formatBySquareRecommendList($articleIds, $currentUserId)
    {
        $articleArr = self::getArticleArr($articleIds);
        $authorArr = UserFormat::getUserArr(ArrayHelper::getColumn($articleArr, 'author_id'), UserSelect::ARTICLE);

        $list = [];
        /**
         * @var SysArticle $article
         */
        foreach ($articleArr as $article) {
            /**
             * 推荐头像区域可能为空，推荐数一定为0，此时需要：
             *  1.推荐数在20-50区间
             *  2.头像区域随机
             */
            $count = service()->CounterService->getArticleCount($article->article_id, $currentUserId, ['collect', 'note', 'recommend']);
            if (empty($count['recommend']) || $count['recommend'] == 0) {
                $count['recommend'] = rand(20, 50);
            }
            $article = $articleArr[$article->article_id]->commonFormat(ArticleField::DYNAMIC);

            $list[] = ArrayHelper::merge($article, [
                'author' => isset($authorArr[$article['author_id']]) && $article['type'] == GlobalArticleConst::ARTICLE_TYPE_ORIGINAL ? $authorArr[$article['author_id']]->commonFormat(UserField::ARTICLE_LANDING) : (object)[],
                'target_type' => GlobalConst::TARGET_TYPE_ARTICLE,
                'recommend' => self::getArticleRecommendAvatar($article['id']),
                'count' => $count,
            ]);
        }

        return $list;
    }

    public static function formatBySimilarArticleList($articleIds)
    {
        $articleArr = self::getArticleArr($articleIds);

        $list = [];
        /**
         * @var SysArticle $article
         */
        foreach ($articleArr as $article) {
            $list[] = $article->commonFormat(ArticleField::SIMILAR_ARTICLE);
        }

        return $list;
    }

    public static function getArticleArr($articleIds, $selectScene = ArticleSelect::SELF_LIST)
    {
        $articleArr = [];

        $articleIdTable = IdBuilder::getSubTable($articleIds);
        foreach ($articleIdTable as $tableCount => $articleIdArr) {
//            dump($articleIdArr);
            $model = repository()->ArticleRepository
                ->getArticleByTableCount($tableCount, $articleIdArr, $selectScene);
            $articleArr = ArrayHelper::merge($model, $articleArr);
        }

        return ArrayHelper::index($articleArr, 'article_id');
    }

    public static function getArticleRecommendAvatar($articleId)
    {
        $recommendListAvatarArea = Oss::getInstance(GlobalUploadConst::RECOMMEND_LIST_AVATAR_AREA)
            ->getObject($articleId . '.json');
        if ($recommendListAvatarArea && Json::decode($recommendListAvatarArea, true)) {
            return Json::decode($recommendListAvatarArea, true);
        }

        $ossInfoJson = Oss::getInstance(GlobalUploadConst::RECOMMEND_LIST_AVATAR_AREA)->getObject('robot.json');
        $ossInfo = Json::decode($ossInfoJson, true);
        return $ossInfo ? collect($ossInfo)->random(GlobalDynamicConst::AVATAR_AREA_COUNT) : [];
    }
}
